package developer.算法.双指针.接雨水;


/**
 * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。
 */
public class Jieyushui_self {
    public static void main(String[] args) {
        int jieshui = jieshui(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1});
//        int jieshui = jieshui(new int[]{4,2,0,3,2,5});
        System.out.println(jieshui);
    }

    /**
     * 官方答案：
     * 两个指针没有相遇时，进行如下操作：
     * <p>
     * 使用 height[left] 和 height[right] 的值更新 leftMax 和 rightMax 的值；
     * <p>
     * 如果 height[left]<height[right]，则必有 leftMax<rightMax，下标 left 处能接的雨水量等于 leftMax−height[left]，将下标 left 处能接的雨水量加到能接的雨水总量，然后将 left 加 1（即向右移动一位）；
     * <p>
     * 如果 height[left]≥height[right]，则必有 leftMax≥rightMax，下标 right 处能接的雨水量等于 rightMax−height[right]，将下标 right 处能接的雨水量加到能接的雨水总量，然后将 right 减 1（即向左移动一位）。
     * <p>
     * 作者：力扣官方题解
     * 链接：https://leetcode.cn/problems/trapping-rain-water/solutions/692342/jie-yu-shui-by-leetcode-solution-tuvc/
     * 来源：力扣（LeetCode）
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     * <p>
     * <p>
     * 问题核心在于：
     * 谁矮 谁接水少
     * 如果左侧比右边矮  那么我接的水就是左侧的最高点减去我当前模块的高度
     * 也能得出一个结论   height[left]<height[right]，则必有 leftMax<rightMax
     * 因为但凡你的左边有比 rightMax 大的 你也不会走到这里
     * 太妙了！
     *
     * @param height
     * @return
     */
    public static int jieshui(int[] height) {
        int ans = 0;
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            //左侧最高值
            leftMax = Math.max(leftMax, height[left]);
            //右侧最高值
            rightMax = Math.max(rightMax, height[right]);
            //                       |
            //如果当前左侧 小于当前右侧| |
            if (height[left] < height[right]) {
                ans += leftMax - height[left];//左侧最高点-当前左侧
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;

    }

    private static int calcVal(int left, int right, int[] nums) {
        if (left < 0) return 0;
        int tempResult = 0;
        int leftVal = nums[left];
        int rightVal = nums[right];
        int minHeight = Math.min(leftVal, rightVal);
        for (int i = left + 1; i < right; i++) {
            int r = minHeight - nums[i];
            tempResult += r;
        }
        return tempResult;
    }
}
